#include "LabelObject.h"

OBJECT_DEFINE_START (LabelObject, label_object)

void
label_object_init (LabelObject* obj)
{
        object_node_init (OBJECT_NODE (obj));
        object_set_destory_func (obj, label_object_destory);
        obj->cache_for_value = NULL;
        obj->key             = NULL;
        obj->label_state     = LABEL_OBJECT_STATE_START;
        obj->value_head      = NULL;
        obj->value_type      = VALUE_TYPE_UNINIT;
}

void
label_object_destruction (LabelObject* obj)
{
        object_unref (obj->key);
        object_unref (obj->cache_for_value);
        object_unref (obj->value_head);
        object_node_destruction (OBJECT_NODE (obj));
}

void
label_object_set_key (LabelObject* obj, ObjectString* key)
{
        if (!obj || !key)
                return;
        obj->key = object_string_reference (key);
}

void
label_object_set_type (LabelObject* obj, ValueType type)
{
        obj->value_type = type;
}

static void
label_object_add_value (LabelObject* obj, ValueObject* value)
{
        if (!obj || !value) {
                OBJECT_ERROR_TOOL (LabelObject, add_value, "参数载入出错！\n");
                return;
        }

        if (obj->value_head == NULL) {
                obj->value_head = object_reference_to (value, VALUE_OBJECT);
                object_node_set_as_manager (OBJECT_NODE (value));
        } else {
                object_node_set_new_end (
                        OBJECT_NODE (obj->value_head),
                        object_reference_to (value, OBJECT_NODE));
        }
}

static LabelObjectEvent
label_object_catch_event (char ch)
{
        if (ch == '-' || ch == '.' || (ch >= '0' && ch <= '9'))
                return LABEL_OBJECT_EVENT_VALUEC;
        switch (ch) {
        case '{':
                return LABEL_OBJECT_EVENT_LEFT;
        case '}':
                return LABEL_OBJECT_EVENT_RIGHT;
        case ' ':
        case ',':
                return LABEL_OBJECT_EVENT_COMMA;
        case '\0':
                return LABEL_OBJECT_EVENT_ENDL;
        default:
                return LABEL_OBJECT_EVENT_OTHER;
        }
}

int
label_object_analysis_value (LabelObject*             obj,
                             ObjectStringApplication* str_value)
{
        // bool             is_direct_value = false;
        char             buf[2] = {'\0', '\0'};
        int              state  = 0;
        LabelObjectEvent event;
        ValueObject*     value_obj = NULL;

        if (!obj || !str_value) {
                OBJECT_ERROR_TOOL (LabelObject,
                                   analysis_value,
                                   "传入参数有误！\n");
                return 1;
        }

        if (obj->value_type == VALUE_TYPE_UNINIT) {
                obj->value_type = value_fetch_type (str_value);
                OBJECT_INFO_TOOL (LabelObject,
                                  analysis_value,
                                  "自动检测类型: %d\n",
                                  obj->value_type);
        }

        if (obj->value_type == VALUE_TYPE_ERROR) {
                OBJECT_ERROR_TOOL (
                        LabelObject,
                        analysis_value,
                        "Value "
                        "值不能被识别，或格式有误！(VALUE_TYPE_ERROR)"
                        "，原字符串: '%s'\n",
                        object_string_get_string (OBJECT_STRING (str_value)));
                return 1;
        }

        object_addref (str_value);

        object_string_application_rewind (str_value);
        obj->cache_for_value = object_string_application_new ();
reanalysis:
        if (obj->label_state != LABEL_OBJECT_STATE_FAILED) {
                buf[0] = object_string_application_iter (str_value);
                event  = label_object_catch_event (buf[0]);
        }
        switch (obj->label_state) {
        case LABEL_OBJECT_STATE_START: {
                if (event == LABEL_OBJECT_EVENT_LEFT) {
                        obj->label_state = LABEL_OBJECT_STATE_RECV_DEFAULT;
                } else if (event == LABEL_OBJECT_EVENT_VALUEC ||
                           event == LABEL_OBJECT_EVENT_OTHER) {
                        object_string_append_string (
                                OBJECT_STRING (obj->cache_for_value),
                                buf);
                        // is_direct_value  = true;
                        obj->label_state = LABEL_OBJECT_STATE_RECV_DIRECT;
                } else if (event == LABEL_OBJECT_EVENT_RIGHT) {
                        OBJECT_ERROR_TOOL (LabelObject,
                                           analysis_value,
                                           "'}' 不能在最前。\n");
                        obj->label_state = LABEL_OBJECT_STATE_FAILED;
                } else if (event == LABEL_OBJECT_EVENT_COMMA) {
                        OBJECT_ERROR_TOOL (LabelObject,
                                           analysis_value,
                                           "',' 不能在最前。\n");
                        obj->label_state = LABEL_OBJECT_STATE_FAILED;
                } else if (event == LABEL_OBJECT_EVENT_ENDL) {
                        OBJECT_ERROR_TOOL (LabelObject,
                                           analysis_value,
                                           "没有检测到任何值。\n");
                        obj->label_state = LABEL_OBJECT_STATE_FAILED;
                }
                break;
        }
        case LABEL_OBJECT_STATE_RECV_DEFAULT: {
                if (event == LABEL_OBJECT_EVENT_VALUEC) {
                        object_string_append_string (
                                OBJECT_STRING (obj->cache_for_value),
                                buf);
                } else if (event == LABEL_OBJECT_EVENT_COMMA) {
                        obj->label_state = LABEL_OBJECT_STATE_REFRESH;
                } else if (event == LABEL_OBJECT_EVENT_RIGHT) {
                        obj->label_state = LABEL_OBJECT_STATE_ENDL;
                } else if (event == LABEL_OBJECT_EVENT_ENDL) {
                        OBJECT_ERROR_TOOL (
                                LabelObject,
                                analysis_value,
                                "Value 意外提前结束。原始值: "
                                "'%s\033[01;31m^~~~\033[0m'\n",
                                object_string_get_string (
                                        OBJECT_STRING (obj->cache_for_value)));
                        obj->label_state = LABEL_OBJECT_STATE_FAILED;
                } else if (event == LABEL_OBJECT_EVENT_LEFT) {
                        OBJECT_ERROR_TOOL (LabelObject,
                                           analysis_value,
                                           "不允许两个左花括号出现！\n");
                        obj->label_state = LABEL_OBJECT_STATE_FAILED;
                } else if (event == LABEL_OBJECT_EVENT_OTHER) {
                        OBJECT_ERROR_TOOL (LabelObject,
                                           analysis_value,
                                           "Value 字符串 '%s' 中有未定义的字符 "
                                           "'\033[01;31m%c\033[0m'\n",
                                           object_string_get_string (
                                                   OBJECT_STRING (str_value)),
                                           *(str_value->ch_ip - 1));
                        obj->label_state = LABEL_OBJECT_STATE_FAILED;
                }
                break;
        }
        case LABEL_OBJECT_STATE_RECV_DIRECT: {
                if (event == LABEL_OBJECT_EVENT_ENDL) {
                        object_unref (value_obj);
                        value_obj = value_object_new ();
                        state     = value_object_load_as_type (
                                value_obj,
                                obj->value_type,
                                obj->cache_for_value);
                        if (state == 1) {
                                OBJECT_ERROR_TOOL (
                                        LabelObject,
                                        analysis_value,
                                        "载入 Value 出错！(条件 "
                                        "RECV_DIRECT)，原始值: '%s'\n",
                                        object_string_get_string (
                                                OBJECT_STRING (str_value)));
                                obj->label_state = LABEL_OBJECT_STATE_FAILED;
                        } else {
                                label_object_add_value (obj, value_obj);
                                obj->label_state = LABEL_OBJECT_STATE_EXIT;
                        }
                } else {
                        object_string_append_string (
                                OBJECT_STRING (obj->cache_for_value),
                                buf);
                }
                break;
        }
        case LABEL_OBJECT_STATE_REFRESH: {
                /*刷新并取得数据时，使用 value_object_load_as_type 载入 Value*/
                if (event == LABEL_OBJECT_EVENT_VALUEC) {
                        object_unref (value_obj);
                        value_obj = value_object_new ();
                        state     = value_object_load_as_type (
                                value_obj,
                                obj->value_type,
                                obj->cache_for_value);
                        if (state == 1) {
                                OBJECT_ERROR_TOOL (
                                        LabelObject,
                                        analysis_value,
                                        "载入 Value 值出错！(条件 "
                                        "REFRESH)，原始值: '%s'\n",
                                        object_string_get_string (
                                                OBJECT_STRING (str_value)));
                                obj->label_state = LABEL_OBJECT_STATE_FAILED;
                        } else {
                                label_object_add_value (obj, value_obj);
                                object_string_set_string (
                                        OBJECT_STRING (obj->cache_for_value),
                                        buf);
                                obj->label_state =
                                        LABEL_OBJECT_STATE_RECV_DEFAULT;
                        }
                } else if (event == LABEL_OBJECT_EVENT_RIGHT) {
                        obj->label_state = LABEL_OBJECT_STATE_ENDL;
                } else if (event == LABEL_OBJECT_EVENT_ENDL) {
                        OBJECT_ERROR_TOOL (
                                LabelObject,
                                analysis_value,
                                "缺少右花括号 '%s\033[01;31m^~~~\033[0m'\n",
                                object_string_get_string (
                                        OBJECT_STRING (str_value)));
                        obj->label_state = LABEL_OBJECT_STATE_FAILED;
                } else if (event == LABEL_OBJECT_EVENT_OTHER) {
                        OBJECT_ERROR_TOOL (LabelObject,
                                           analysis_value,
                                           "字符串 '%s' 中出现未定义字符 "
                                           "'\033[01;31m%c\033[0m'\n",
                                           object_string_get_string (
                                                   OBJECT_STRING (str_value)),
                                           *(str_value->ch_ip - 1));
                        obj->label_state = LABEL_OBJECT_STATE_FAILED;
                } else if (event == LABEL_OBJECT_EVENT_LEFT) {
                        OBJECT_ERROR_TOOL (LabelObject,
                                           analysis_value,
                                           "Value 字符串中多出现了一个 '{'\n");
                        obj->label_state = LABEL_OBJECT_STATE_FAILED;
                }
                break;
        }
        case LABEL_OBJECT_STATE_ENDL: {
                if (event == LABEL_OBJECT_EVENT_ENDL) {
                        object_unref (value_obj);
                        value_obj = value_object_new ();
                        state     = value_object_load_as_type (
                                value_obj,
                                obj->value_type,
                                obj->cache_for_value);
                        if (state == 1) {
                                OBJECT_ERROR_TOOL (
                                        LabelObject,
                                        analysis_value,
                                        "Value 数值载入出错！(条件 ENDL)\n");
                                obj->label_state = LABEL_OBJECT_STATE_FAILED;
                        } else {
                                label_object_add_value (obj, value_obj);
                                obj->label_state = LABEL_OBJECT_STATE_EXIT;
                        }
                } else {
                        OBJECT_ERROR_TOOL (LabelObject,
                                           analysis_value,
                                           "字符串中 '}' "
                                           "代表结束，其后不应有任何字符。"
                                           "'%s\033[01;31m^~~~\033[0m'\n",
                                           object_string_get_string (
                                                   OBJECT_STRING (str_value)));
                        obj->label_state = LABEL_OBJECT_STATE_FAILED;
                }
                break;
        }
        case LABEL_OBJECT_STATE_FAILED: {
                OBJECT_ERROR_TOOL (LabelObject,
                                   analysis_value,
                                   "此阶段出现错误。\n");
                object_unref (str_value);
                object_unref (value_obj);
                return 1;
        }
        case LABEL_OBJECT_STATE_EXIT:
                object_unref (str_value);
                object_unref (value_obj);
                return 0;
        }

        goto reanalysis;
}
